package edu.cs.usask.ca.silver.plugin.rcp.dialogs.create;

import java.util.Hashtable;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;

import edu.cs.usask.ca.silver.api.persistence.StorageI;
import edu.cs.usask.ca.silver.businesslogic.ids.ParameterID;
import edu.cs.usask.ca.silver.businesslogic.ids.ScenarioID;
import edu.cs.usask.ca.silver.plugin.rcp.components.SilverNameEnums;

/**
 * This class is used to supply the contents to be displayed in the tableviewer.
 * It contains an array of hashtables. Each hashtable contains the data
 * associated with a single parameter. This includes the parameter name, type,
 * value, units, and comments (A comment is a description of way a value was
 * chosen for a specific parameter, which is different from a parameter
 * description describing the parameter itself). When the user edits the data in
 * the new scenario dialog, it is this array that is edited, thus we do not have
 * to worry about the state of the database if the user cancels the action.
 * 
 * Note that we have extended this class to handle the case where the system
 * populates the VALUES (only) of the parameters using data from a trajectory
 * file We do this by passing in a map from parameter id to value
 * 
 * 
 * similar to "AddScenarioTableContentProvider.java"
 * 
 * 
 * @author Mike Taylor
 * @author Yudi Xue
 * @author Nate Osgood
 * 
 */
public class CreateScenarioTableContentProvider implements
		IStructuredContentProvider {

	public static Hashtable<String, String>[] fakeParams;
	public static ParameterID[] parameterIds = null;
	private final ScenarioID scenarioId;
	private final StorageI myStorage;
	private static Logger logger = Logger.getLogger(CreateScenarioTableContentProvider.class);

	public CreateScenarioTableContentProvider(ParameterID[] parameterIds,
			ScenarioID scenarioId, StorageI storage) {

		this.parameterIds = parameterIds;
		this.scenarioId = scenarioId;
		fakeParams = new Hashtable[this.parameterIds.length];
		myStorage = storage;
		initData();
	}

	/**
	 * this method populates the array of hashtables used by the new scenario
	 * dialog box, and is edited by the user
	 */
	private void initData() {
		try {
			for (int i = 0; i < parameterIds.length; i++) {
				fakeParams[i] = new Hashtable<String, String>();
				fakeParams[i].put(SilverNameEnums.NAME.name(),
						parameterIds[i].getEntryNameFromDatabase(myStorage));
				fakeParams[i].put(SilverNameEnums.TYPE.name(),
						parameterIds[i].getTypeFromDatabase(myStorage));
				fakeParams[i].put(SilverNameEnums.VALUE.name(),
						scenarioId.getParameterValue(parameterIds[i], myStorage));
				fakeParams[i].put(SilverNameEnums.UNITS.name(),
						parameterIds[i].getUnit(myStorage));
				fakeParams[i].put(SilverNameEnums.COMMENT.name(),
						scenarioId.getParameterComment(parameterIds[i], myStorage));

				logger.info("Name : "
						+ fakeParams[i].get(SilverNameEnums.NAME.name()));
				logger.info("Type : "
						+ fakeParams[i].get(SilverNameEnums.TYPE.name()));
				logger.info("Value : "
						+ fakeParams[i].get(SilverNameEnums.VALUE.name()));
				logger.info("Units : "
						+ fakeParams[i].get(SilverNameEnums.UNITS.name()));
				logger.info("Comments : "
						+ fakeParams[i].get(SilverNameEnums.COMMENT.name()));
			}
		} catch (Exception e) {
			// TODO: Unable to print out parameter list
		}

	}/* end of init */

	void overrideParameterValues(Map<Integer, Double> mapParameterIDToDouble) {

		/******
		 * The below was a problem when we were using a map Map<ParameterID,
		 * Double> . It would be highly desirable to use such a map, but the
		 * code below shows a bug with it. TODO This needs to be figured out and
		 * fixed;
		 * 
		 * for (ParameterID parmIdTest : mapParameterIDToDouble.keySet()) { if
		 * (parmIdTest.getIdVal() == 163) { ParameterID p = parameterIds[0]; if
		 * (parmIdTest.equals(p)) logger.info("Matches!"); // this
		 * successfully matches else logger.info("No Match!");
		 * 
		 * // the next two return corrrect references Object o1 =
		 * mapParameterIDToDouble.get(parmIdTest); Double d1 =
		 * mapParameterIDToDouble.get(parmIdTest);
		 * 
		 * // thse both return 0, despite the fact that parmIdTest.equals(p)!
		 * Object o2 = mapParameterIDToDouble.get(p); Double d2 =
		 * mapParameterIDToDouble.get(p);
		 * 
		 * logger.info("o1 = " + o1 + ", o2 = " + o2 + ", d1 = " + d1 +
		 * ", d2 = " + d2);
		 * 
		 * } } if (mapParameterIDToDouble.containsKey(parameterIds[0]))
		 * logger.info("In collection!"); else
		 * logger.info("Not in collection!"); // was returning this
		 ***/

		// update the values associated with each parameter using the map
		for (int i = 0; i < parameterIds.length; i++) {
			ParameterID parameterId = parameterIds[i];
			// boolean boolDebug =
			// mapParameterIDToDouble.containsKey(parameterId);
			Double dOverriddenValue = mapParameterIDToDouble.get(parameterId
					.getIdVal());
			System.out
					.println("Changing value in create new scenario dialogue from : "
							+ fakeParams[i].get(SilverNameEnums.VALUE.name())
							+ " to " + dOverriddenValue);

			fakeParams[i].put(SilverNameEnums.VALUE.name(),
					dOverriddenValue.toString());
		}
	}

	/**
	 * a method that returns the array for the new scenario column label
	 * provider for the tableviewer
	 * 
	 * @return array of hashtable to the new scenario action class so the edited
	 *         data can be persisted
	 */

	public static Hashtable<String, String>[] getNewScenarioData() {
		return fakeParams;
	}

	public static ParameterID[] getParameterIDData() {
		return parameterIds;
	}

	/**
	 * a method that returns the array for the new scenario column label
	 * provider for the tableviewer
	 * 
	 * @return array of hashtable to the label provider
	 */
	public Object[] getElements(Object inputElement) {
		// TODO Auto-generated method stub
		return fakeParams;
	}

	public void dispose() {
		// TODO Auto-generated method stub

	}

	public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
		// TODO Auto-generated method stub

	}

} /* end of class */
